# -*- coding: utf_8 -*-
# @Create   : 2021/8/31 16:49
# @Author   : yh
# @Remark   : 建立视频质量分析
import os
import sys

from mxsoftpy.TableDB import TableDB
from mxsoftpy.TreeDB import TreeDB
from mxsoftpy.db_def.def_table import BS_TDTF_FLAG_AUTOID
from mxsoftpy.exception import DBError

base_path = os.path.dirname(os.path.dirname(os.path.dirname((os.path.abspath(__file__)))))
sys.path.insert(0, base_path)
sys.path.insert(0, os.path.dirname(base_path))

from model.common.VideoManage.VideoQuality.inspection_record import InspectionRecordModel
from server.common.VideoManage.VideoQuality.conf import VideoDeviceServer, StreamServer, ResolutionServer, \
    TaskCycleServer, TestItemsServer
from utils.conf.mxconfig import MxConfig

"""
!!!!!!!!!!!!!!!!!!!!
* 需要在数据库中创建 IOT 数据库。
* IP会读取配置中的HOST
* 执行完脚本需要刷新 IOT 数据库 ！！！
如果需要自定义数据库名和主键名，需修改database_data下面的 main_data 和 one_path 的key
"""


def database_data():
    """数据库键信息"""
    main_data = "IOT"
    one_path = {"VideoQuality": {'desc': "视频资料分析"}}
    two_path = {"Conf": {'desc': "用于存放所有的配置项"},
                "InspectionPlan": {'desc': "巡检计划"},
                "InspectionTask": {'desc': "巡检任务"},
                "RepairWarehouse": {'desc': "待修库"},
                "Video": {'desc': "视频"},
                "VideoGroup": {'desc': "视频组"},
                "TestImage": {'desc': "测试图像"}
                }
    return main_data, one_path, two_path


def conf_data():
    """数据库配置设备信息"""
    key_name = "Conf"
    one_path = {"DeviceType": {'desc': "设备类型"},
                "Resolution": {'desc': "分辨率"},
                "Stream": {'desc': "码流"},
                "TaskCycle": {'desc': "任务周期"},
                "TestItems": {'desc': "检测项目"}}
    return key_name, one_path


def devicetype_data():
    """设备类型的数据"""
    devicetype_key = "DeviceType"
    devicetype_server = VideoDeviceServer
    devicetypedata = [{'name': "摄像头", "state": 1},
                      {'name': "录像机", "state": 1},
                      {'name': "其他", "state": 1}]
    return devicetype_key, devicetype_server, devicetypedata


def resolution_data():
    """分辨率的数据"""
    resolution_key = "Resolution"
    resolution_server = ResolutionServer
    resolutiondata = [{'name': "176*44", "state": 1},
                      {'name': "352*288", "state": 1},
                      {'name': "704*576", "state": 1},
                      {'name': "640*480", "state": 1},
                      {'name': "720*480", "state": 1},
                      {'name': "1280*720", "state": 1},
                      {'name': "1920*1080", "state": 1},
                      {'name': "2560*1440", "state": 1}]
    return resolution_key, resolution_server, resolutiondata


def stream_data():
    """码流的数据"""
    stream_key = "Stream"
    stream_server = StreamServer
    streamdata = [{'name': "主码流", "state": 1, 'value': 1},
                  {'name': "副码流", "state": 1, 'value': 2}]
    return stream_key, stream_server, streamdata


def taskcycle_data():
    """任务周期数据"""
    taskcycle_key = "TaskCycle"
    taskcycle_server = TaskCycleServer
    taskcycledata = [{'name': "每1小时", "state": 1, 'minute': 60},
                     {'name': "每2小时", "state": 1, 'minute': 120},
                     {'name': "每8小时", "state": 1, 'minute': 480},
                     {'name': "每12小时", "state": 1, 'minute': 720},
                     {'name': "每天", "state": 1, 'minute': 1440},
                     {'name': "每周", "state": 1, 'minute': 10080}]
    return taskcycle_key, taskcycle_server, taskcycledata


def testitems_data():
    """检测类型数据"""
    testitems_key = 'TestItems'
    testitems_server = TestItemsServer
    testitemsdata = [
        # 评估信号丢失 py_evaluateSigloss 参考阈值：>80
        {'name': "信号丢失", "state": 1, 'max': 100.00, 'min': 0.00, 'step': 1.00, 'func_name': 'py_evaluateSigloss',
         'expression': 'value > confidence', 'func_args': 'handle', 'reference': 80.000, },

        # 检测视频冻结 py_evaluateFreeze 参考阈值：<0.01（微小的差异可能由时间显示文本的变化引起）
        {'name': "冻结", "state": 1, 'max': 1.00, 'min': 0.00, 'step': 0.01, 'func_name': 'py_evaluateFreeze',
         'expression': 'value <= confidence', 'func_args': 'url', 'reference': 0.000},

        # 评估偏色 py_evaluateColorCast 参考阈值：>2.0
        {'name': "偏色", "state": 1, 'max': 100.00, 'min': 0.00, 'step': 1.00, 'func_name': 'py_evaluateColorCast',
         'expression': 'value > confidence', 'func_args': 'handle', 'reference': 2.000},

        # 评估清晰度 py_evaluateBlur 参考阈值：<0.8
        {'name': "清晰度", "state": 1, 'max': 10.00, 'min': 0.00, 'step': 0.10, 'func_name': 'py_evaluateBlur',
         'expression': 'value < confidence', 'func_args': 'handle', 'reference': 0.800},

        # 评估镜头遮挡 py_evaluateCover 参考阈值：>0.3
        {'name': "遮挡", "state": 1, 'max': 10.00, 'min': 0.00, 'step': 0.10, 'func_name': 'py_evaluateCover',
         'expression': 'value > confidence', 'func_args': 'handle', 'reference': 0.300},

        # 评估视频抖动 py_evaluateFlutter 参考阈值：>0.1
        {'name': "抖动", "state": 1, 'max': 10.00, 'min': 0.00, 'step': 0.10, 'func_name': 'py_evaluateFlutter',
         'expression': 'value > confidence', 'func_args': 'url', 'reference': 0.100},

        # 雪花噪声检测 py_evaluateNoise 参考阈值：>0.2
        {'name': "雪花", "state": 1, 'max': 1.00, 'min': 0.00, 'step': 0.01, 'func_name': 'py_evaluateNoise',
         'expression': 'value > confidence', 'func_args': 'handle', 'reference': 0.150},

        # 评估图片的亮度异常 py_evaluateBrightness 参考阈值：绝对值>5
        {'name': "亮度异常", "state": 1, 'max': 10.00, 'min': 0.00, 'step': 0.10, 'func_name': 'py_evaluateBrightness',
         'expression': 'abs(value) > confidence', 'func_args': 'handle', 'reference': 2.500},

        # 评估图片的条纹噪音 py_evaluateStripe 参考阈值：绝对值>5
        {'name': "条纹噪音", "state": 0, 'max': 100.00, 'min': 0.00, 'step': 1.00, 'func_name': 'py_evaluateStripe',
         'expression': 'value > confidence', 'func_args': 'handle', 'reference': 30.000},
    ]
    return testitems_key, testitems_server, testitemsdata


class CreateDatabase:

    def __init__(self):
        self.tree = TreeDB()
        self.table = TableDB()
        self.host = MxConfig().HOST
        self.main_key = None
        self.one_path = None
        self.sub_key = None

    def create_database(self, d_data):
        """创建数据库"""
        try:
            """对应参数"""
            main_key, one_path, two_path = d_data
        except ValueError as e:
            print(f'参数数量不正确,{e}')
            return False
        try:
            """添加主键属性"""
            for i in one_path:
                self.tree.insert_main_key(main_key=i, file=main_key, host=self.host)
                self.tree.open(i, file=main_key, host=self.host).insert_items(
                    [(j, one_path[i][j]) for j in one_path[i]])
                for x in two_path:
                    self.tree.insert_key_items(items=[(j, two_path[x][j]) for j in two_path[x]], key=x)
        except DBError as e:
            print(f'键已存在或其他数据库错误,{e}')

        except EOFError as e:
            print(f'python语法错误,{e}')
            return False

        self.main_key = "IOT"
        self.one_path = "VideoQuality"
        print('创建主键,子健操作完成')

    def create_conf_key(self, conf_key):
        try:
            """对应参数"""
            key_name, one_path = conf_key
        except ValueError as e:
            print(f'参数数量不正确,{e}')
            return False
        if not self.main_key and not self.one_path:
            print('请先执行create_database方法')
            return False
        try:
            self.tree.open(self.one_path, key_name, file=self.main_key, host=self.host)
            for i in one_path:
                self.tree.insert_key_items(items=[(j, one_path[i][j]) for j in one_path[i]], key=i)

        except DBError as e:
            print(f'键已存在或其他数据库错误,{e}')
        except EOFError as e:
            print(f'python语法错误,{e}')
            return False

        self.sub_key = key_name
        print('添加Conf配置操作完成')

    def create_table(self):
        """
        创建数据库表，用于存储巡检记录
        """
        self.table.open('MXSE', host='127.0.0.1')
        self.table.create_table('VideoInspectionRecord', InspectionRecordModel,
                                flag=BS_TDTF_FLAG_AUTOID)

    def conf_params(self, params):
        try:
            """对应参数"""
            key_name, key_server, param = params
        except ValueError as e:
            print(f'参数数量不正确,{e}')
            return False
        try:
            for data in param:
                key_server(key_name).add(**data)

            # tree = self.tree.open(self.one_path, f"{self.sub_key}\\{key_name}", file=self.main_key, host=self.host)
            # for i in param:
            #     tree.insert_key_items(items=[(j, i[j]) for j in i])

        except DBError as e:
            print(f'键已存在或其他数据库错误,{e}')
        except EOFError as e:
            print(f'python语法错误,{e}')
            return False
        print(f'添加{key_name}数据操作完成')


if __name__ == '__main__':
    pass
    run = CreateDatabase()

    """创建主键,子健"""
    run.create_database(database_data())
    #
    """添加Conf配置"""
    run.create_conf_key(conf_data())
    #
    """添加配置数据"""
    run.conf_params(devicetype_data())
    #
    """添加分辨率的数据"""
    run.conf_params(resolution_data())
    #
    """添加码流的数据"""
    run.conf_params(stream_data())
    #
    """添加任务周期数据"""
    run.conf_params(taskcycle_data())
    # #
    """添加检测类型数据"""
    run.conf_params(testitems_data())

    # 添加数据库table
    run.create_table()
